package com.earth.amazeadmin.config.mybatis;

import com.earth.amazeadmin.config.mybatis.utils.Constants;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
// 扫描 Mapper 接口并容器管理
@MapperScan(basePackages = SsoDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "ssoSqlSessionFactory")
public class SsoDataSourceConfig {

    // 精确到 cluster 目录，以便跟其他数据源隔离
    static final String PACKAGE = "com.earth.amazeadmin.dao.sso";
    static final String MAPPER_LOCATION = "classpath:mapper/sso/*.xml";

    @Autowired
    private Environment env;

    @Bean(name = "ssoDataSource")
    @Primary
    public DataSource ssoDataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(env.getProperty("spring.datasource.hikari.sso.url"));
        config.setUsername(env.getProperty("spring.datasource.hikari.sso.username"));
        config.setPassword(env.getProperty("spring.datasource.hikari.sso.password"));
        //config.setDataSourceClassName(env.getProperty("spring.datasource.type"));
        config.setDriverClassName(env.getProperty("spring.datasource.hikari.driver-class-name"));
        config.addDataSourceProperty("minimumIdle", env.getProperty("spring.datasource.hikari.minimum-idle"));
        config.addDataSourceProperty("maximumPoolSize", env.getProperty("spring.datasource.hikari.maximum-pool-size"));
        config.addDataSourceProperty("initializationFailTimeout", 10000);
        config.addDataSourceProperty("autoCommit", env.getProperty("spring.datasource.hikari.auto-commit"));
        config.addDataSourceProperty("idleTimeout", env.getProperty("spring.datasource.hikari.idle-timeout"));
        config.addDataSourceProperty("poolName", env.getProperty("spring.datasource.hikari.pool-name"));
        config.addDataSourceProperty("maxLifetime", env.getProperty("spring.datasource.hikari.max-lifetime"));
        config.addDataSourceProperty("connectionTimeout", env.getProperty("spring.datasource.hikari.connection-timeout"));
        config.addDataSourceProperty("connectionTestQuery", env.getProperty("spring.datasource.hikari.connection-test-query"));
        config.addDataSourceProperty("useServerPrepStmts", true);
        config.addDataSourceProperty("cachePrepStmts", true);
        return new HikariDataSource(config);
    }

    /**
     * 数据源 jdbcTemplate bean
     *
     * @return
     */
    @Bean(name = "ssoJdbcTemplate")
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(ssoDataSource());
    }

    @Bean(name = "ssoTransactionManager")
    @Primary
    public DataSourceTransactionManager ssoTransactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(ssoDataSource());
        return dataSourceTransactionManager;
    }

    @Bean(name = "ssoSqlSessionFactory")
    @Primary
    public SqlSessionFactory ssoSqlSessionFactory()
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(ssoDataSource());
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(MasterDataSourceConfig.MAPPER_LOCATION));
        sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver()
                .getResource(MasterDataSourceConfig.SHARE_CONFIG_LOCATION));
        return sessionFactory.getObject();
    }
}